//__gnu_debug::set
#include "pch.h"


// DEBUGGING

#define NDEBUG = 1
#define BOOST_DISABLE_ASSERTS
//#define DEBUG_STL = 1













//
//  Standard headers
// 
#include <cassert>

#include <iostream>
	using std::cerr;
	using std::cout;
	using std::ofstream;
	using std::istream;
#include <utility>
	using std::make_pair;

#include <set>
	using std::set;
#include <vector>
	using std::vector;
#include <string>
	using std::string;
#include <numeric>
#include <algorithm>
	using std::fill_n;
#include <stdexcept>
	using std::runtime_error;
#include <unordered_map>
	using std::unordered_map;
#include <unordered_set>
	using std::unordered_set;
#include <tuple>
	using std::get;
	using std::tuple;
	using std::tie;
	using std::pair;


//
//  My common headers
// 
//#include <tuple_hash.h>
//#include <unique_file_name_with_replacement.h>
//#include <progress_indicator.h>
//#include <commify.h>
//#include <portable_timer.h>
//#include <intervals_per_contig.h>
//	using intervals_per_contig::t_intervals_per_contig;
//	using intervals_per_contig::t_interval_search_cache;
//	using intervals_per_contig::t_intervals;
//	using intervals_per_contig::ci_map_str_intervals;
//
//#include <open_stream_name_with_substitutions.h>
//
//
//#include <get_col_names_from_header.h>
//using parsing::parse_error;
//using parsing::get_col_names_from_header;





//
//  Boost headers
// 
//#include <boost/algorithm/string/replace.hpp>
//	using boost::replace_all_copy;
#include <boost/algorithm/string.hpp>
//    using boost::join;
	using boost::algorithm::replace_all;

///#include <boost/lexical_cast.hpp>
//	using boost::lexical_cast;
//#include <boost/regex.hpp>
//	using boost::regex;
//#include <boost/functional/hash.hpp>
//	using boost::hash_combine;
//#include <boost/iterator/counting_iterator.hpp>
//	using boost::make_counting_iterator;



//
//	Boost Spirit
// 
//#include <boost/spirit/include/qi.hpp>
//	namespace qi = boost::spirit::qi;
//#include <boost/spirit/include/support_multi_pass.hpp>
//#include <boost/spirit/include/karma.hpp>
//	namespace karma = boost::spirit::karma;
//	using boost::spirit::karma::uint_;
//	using boost::spirit::karma::lit;
//	using boost::spirit::karma::generate;
//#include <boost/fusion/include/adapt_struct.hpp>
//#include <boost/fusion/include/io.hpp>
//#include <boost/spirit/include/phoenix_core.hpp>
//namespace phoenix = boost::phoenix;
//#include "qi_parse_error_handler.h"
//
//#include <boost/filesystem.hpp>
//	using boost::filesystem::path;
//	using boost::filesystem::file_size;
//	using boost::filesystem::is_regular_file;
//	using boost::filesystem::basename;
//
//#include <boost/array.hpp>
//	using boost::array;
//#include <boost/foreach.hpp>
//
//#include <boost/range/algorithm_ext/push_back.hpp>
//    using boost::push_back;
//#include <boost/range/numeric.hpp>
//	using boost::accumulate;
//#include <boost/range/algorithm.hpp>
//	using boost::sort;
//	using boost::reverse;
//	using boost::for_each;
//#include <boost/range/numeric.hpp>
//	using boost::accumulate;
//#include <boost/range/adaptors.hpp>
//
//
//#include <boost/iostreams/device/file.hpp>
//#include <boost/iostreams/stream.hpp>
//#include <boost/iostreams/device/mapped_file.hpp>
//	namespace io = boost::iostreams;
//#include <boost/assert.hpp> 


#include <boost/format.hpp>
	using boost::format;


#include "boost/multi_array.hpp"
	using boost::multi_array;
	using boost::const_multi_array_ref;
	using boost::extents;

#ifdef DEBUG_STL
	#include <debug/set>
	#include <debug/vector>
	using __gnu_debug::set;
	using __gnu_debug::vector;
#else
	using std::set;
	using std::vector;
#endif



#include "read_options.h"


void do_main(prog_options& opt);

//________________________________________________________________________________________
// 
//  	Main
//			boilerplate to catch errors
// 
//________________________________________________________________________________________
int print_error_message(string error_string)
{
	replace_all(error_string, "\n", "\n\t");
	std::cerr
			<< "\n"<< string(60, '=') << "\n"
			<< "\nError:\n\t" << error_string 
			<< "\n\n" << string(60, '=') << "\n\n";
	return -1;
}
int main (int argc, char *argv[])
{
	try
	{
		// 
		//  Read options
		//  	return if user chose help or version
		// 
		prog_options opt;
		if (!read_options(opt, argc, argv))
			return 0;

		do_main(opt);

	}
	catch (boost::program_options::validation_error& e)
	{
		return print_error_message(e.what()  + string(" of ") + e.get_option_name());
	}
	catch (boost::program_options::multiple_occurrences& e)
	{
		return print_error_message(e.what()  + string(" of ") + e.get_option_name());
	}
	catch(const std::exception& e)
	{
		return print_error_message(e.what());
	}
	catch (...)
	{
		return print_error_message("Unexpected exception of unknown type.");
	}
	return 0;
}



void throw_logic_error(format& f)
{
	throw std::logic_error(f.str());
}






void do_main(prog_options& opt)
{
}



